package yawning.mew.equipment;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import yawning.mew.equipment.RawItem.Property;

public class Item {
	public RawItem mItem;
	public RawItem mSocket1;
	public RawItem mSocket2;
	public RawItem mSocket3;
	public RawItem mEnchant;
	public Property mReforgeFrom;
	public Property mReforgeTo;

	private static List<Property> sReforgeableProperties = Arrays.asList(
			Property.SPIRIT,
			Property.EXPERTISE_RATING,
			Property.HIT_RATING,
			Property.CRIT_RATING,
			Property.HASTE_RATING,
			Property.DODGE_RATING,
			Property.PARRY_RATING,
			Property.MASTERY_RATING);
	
	public Property[] getValidSrcReforges() {
		if (mItem == null) return null;
		List<Property> list = new LinkedList<Property>();
		for (Property p : sReforgeableProperties) {
			if (mItem.properties.containsKey(p)) list.add(p);
		}
		return list.toArray(new Property[0]);
	}

	public Property[] getValidDstReforges() {
		if (mItem == null) return null;
		Set<Property> list = new HashSet<Property>(sReforgeableProperties);
		for (Property p : sReforgeableProperties) {
			if (mItem.properties.containsKey(p)) list.remove(p);
		}
		return list.toArray(new Property[0]);
	}
	
	public boolean reforge(Property src, Property dst) {
		if (!sReforgeableProperties.contains(src)) return false;
		if (!sReforgeableProperties.contains(dst)) return false;
		if (mItem.properties.containsKey(dst)) return false;
		if (!mItem.properties.containsKey(src)) return false;
		
		mReforgeFrom = src;
		mReforgeTo = dst;
		return true;
	}
	
	public int sumProperty(Property p) {
		int total = 0;
		if (mItem.properties.containsKey(p)) total += mItem.properties.get(p);
		if (mReforgeFrom == p) total -= 0.4 * total;
		if (mReforgeTo == p) total += 0.4 * total;
		if (mSocket1 != null && mSocket1.properties.containsKey(p)) total += mSocket1.properties.get(p);
		if (mSocket2 != null && mSocket2.properties.containsKey(p)) total += mSocket2.properties.get(p);
		if (mSocket3 != null && mSocket3.properties.containsKey(p)) total += mSocket3.properties.get(p);
		if (mEnchant != null && mEnchant.properties.containsKey(p)) total += mEnchant.properties.get(p);
		
		if (mItem.properties.containsKey(Property.SOCKET_BONUS_STAT)) {
			if (mItem.properties.get(Property.SOCKET_BONUS_STAT) == p.ordinal()) {
				boolean bonus = true;
				bonus &= testMatch(mSocket1, Property.SOCKET1);
				bonus &= testMatch(mSocket1, Property.SOCKET1);
				bonus &= testMatch(mSocket1, Property.SOCKET1);
				if (bonus) total += mItem.properties.get(Property.SOCKET_BONUS_VALUE);
			}
		}
		
		return total;
	}
	
	// Gem colors: 0 = red; 1 = blue, 2 = yellow, 3 = purple, 4 = green, 5 = ornage, 6 = meta
	
	private boolean testMatch(RawItem gem, Property slot) {
		if (gem == null) return false;
		if (!mItem.properties.containsKey(slot)) return true;

		int color = gem.properties.get(Property.SUBCLASS);
		switch (mItem.properties.get(slot)) {
			case 1: // Meta
				if (color == 6) return true;
				else return false;
				
			case 2: // red
				if (color == 0 || color == 6 || color == 3) return true;
				else return false;
				
			case 4: // Yellow
				if (color == 2 || color == 4 || color == 5) return true;
				else return false;
				
			case 8: // Blue
				if (color == 1 || color == 3 || color == 4) return true;
				else return false;
				
			default:
				System.out.println("** mew.equipment.Item: Unrecognized socket type " + mItem.properties.get(slot));
				return true;
		}
	}
}
